/* 
	Banowanie na CFG - zapisuje kilka plikow cfg u klienta z informacja o banie
	CVAR:
	amx_cban_complain_url (domyslnie www.no.unban.com)
		adres strony forum 
	cban_with_amx (domyslnie 0; jesli nie ma amxbans zakomentowac #define AMXBANS 1):
		0 - brak integracji z amx_ban
		1 - przy komendzie amx_ban, jesli czas = 0 i powod zawiera "czit" lub "aktyw" banuje nick
		
	Komendy:
		amx_cban nick|#id
		amx_cunban idBana
		amx_gecbans [numer] - pokazuje max 10 banow wstecz od podanego numeru 
					(jesli numer nie jest podany 10 ostatnich)
*/
//#define AMXBANS 1


#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <regex>
#include <amx_ja>

#if defined AMXBANS
	#include <amxbans_main>
#endif

#define PLUGIN "Config Ban"
#define VERSION "1.0"
#define AUTHOR "Zabjaka"
#define NEXT_BAN_ID "NEXT_BAN_ID"
#define INFO_NAME "hl_num"
#define CBAN_LOG_FILE "cban.log"
#define NAME_SIZE 64

new g_vault;
new gNextBanId;
new gComplainUrl;
#if defined AMXBANS
new gCVarAmxBans;
#endif
new MAX_PLAYERS;


new const timeFormat[] = "%d/%m/%Y - %H:%M:%S";

new const Configi[][] =
{
	"hl",
	"save/custom",
	"save/save",
	"maps/maps",
	"maps/de_dust2",
	"cstrike",
	"gfx/game",
	"models/mdls"
}
new client_banned[33];
new client_ban_info[33][256];
new client_ban_time[33];

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR);
	MAX_PLAYERS = get_maxplayers();
	gComplainUrl = register_cvar("amx_cban_complain_url", "www.no.unban.com");
	#if defined AMXBANS
	gCVarAmxBans = register_cvar("cban_with_amx", "0");
	#endif
	g_vault = nvault_open("ZabiCBan");
	new nVaultData[32];
	
	nvault_get(g_vault, NEXT_BAN_ID, nVaultData, 32);
	gNextBanId = str_to_num(nVaultData);
	if(gNextBanId <= 0)
		gNextBanId = 1;

	register_clcmd("amx_cban", "amxCban", ADMIN_BAN, "amx_cban <gracz lub #authid>");
	register_clcmd("amx_cunban", "amxCunban", ADMIN_BAN, "amx_cunban <IdBana>");
	register_clcmd("amx_getcbans", "amxGetCbans", ADMIN_BAN, "amx_getcbans [IdBana]");
	register_clcmd("amx_cbanmenu", "cBanMenu", ADMIN_BAN);
}

public amx_jakas_metoda(id,sec, msg[]){
	client_print(id, print_console, "moj plugin sec=%d, msg=%s",sec,msg);
}
#if defined AMXBANS

public amxbans_player_flagged(index, sec_left, reason[]){
	if(get_pcvar_num(gCVarAmxBans)){
		if(sec_left == 0 ){
			if(strfind(reason, "czit", 1) > -1 || 
				strfind(reason, "aktyw", 1) > -1){
				if(player && player < MAX_PLAYERS) {
					banPlayer(-1, index);					
				}
			}
		}	
	}
}

#endif
public cBanMenu(id, level, cid){
	if(cmd_access(id,level,cid,1)) {		
		new menu = menu_create("\rConfig Ban Nemu:", "menu_handler");
		new players[32], pnum, tempid;
		new szName[32], szTempid[10];
		get_players(players, pnum);
		for( new i; i<pnum; i++ )
		{        
			tempid = players[i];
			get_user_name(tempid, szName, charsmax(szName));
			num_to_str(tempid, szTempid, charsmax(szTempid));
			menu_additem(menu, szName, szTempid, 0);
		}
		menu_display(id, menu, 0);
	}
	return PLUGIN_HANDLED;
}
public menu_handler(id, menu, item)
{
	if( item == MENU_EXIT )
	{
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}

	new data[6], szName[64];
	new acc, callback;
	menu_item_getinfo(menu, item, acc, data, charsmax(data), szName, charsmax(szName), callback);
	new tempid = str_to_num(data);
	if(tempid > 0 && tempid < MAX_PLAYERS && is_user_connected(tempid) )
	{
		banPlayer(id, tempid);
	}

	menu_destroy(menu);
	return PLUGIN_HANDLED;
}

public amxGetCbans(id, level, cid){

	if(!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED;
		
	new numer[8];
	read_argv(1, numer, 7);
	console_print(id, "Ostatni ban: %d", gNextBanId -1);
	
	new idx;
	new i = gNextBanId - 1;
	if(is_str_num(numer)){
		i = str_to_num(numer) + 10;
	}
	if(i > gNextBanId -1)
		i = gNextBanId - 1;
	if(i < 0 )
		i = 0;
		
	new sBanId[33];
	new nvaultData[256];
	new banExists;
	new timestamp;
	new pattern[] = "\[N\](.*)\[/N\]\[A\](.*)\[/A\]\[U\]Y\[/U\]";
	new num, error[128];
	new regRet;
	new Regex:re = regex_compile(pattern, regRet, error, 127);
	new name[33];
	new admin[33];
	new timeStr[64];
	
	if(re){
		while(i>0){
			if(idx >= 10)
				break;			
			num_to_str(i, sBanId, 32);
			banExists = nvault_lookup(g_vault, sBanId, nvaultData, 255, timestamp);
			if(banExists){
				regex_match_c(nvaultData, re, num);
				//server_print("Result=%d, num=%d, error=%s", re, num, error) ;
				if (num == 3)
				{		
					regex_substr(re, 1, name, 32);
					regex_substr(re, 2, admin, 32);
					format_time ( timeStr, 63, timeFormat, timestamp) ;
					console_print(id, "Data: %s, ID: %d, Admin: %s,  Gracz: %s",timeStr, i, admin, name);
					idx++;
				}
			}
			i--;
		}
		regex_free(re);
	}
	return PLUGIN_HANDLED;
}

banPlayer(id, player, showInfo = 1){
	if(player){
		new name[33];
		new admin[33];
		new nvaultData[256];
		new nvaultKey[33];
		get_user_name(player, name, 32);
		if(id)
			get_user_name(id, admin, 32);
		else
			copy(admin, 32, "AMXBANS");
		
		ZapiszConfigi(player, gNextBanId);

		format(nvaultKey, 32, "%d", gNextBanId);
		format(nvaultData, 255, "[N]%s[/N][A]%s[/A][U]Y[/U]",name, admin);
		nvault_set(g_vault, nvaultKey, nvaultData);
		log_to_file(CBAN_LOG_FILE, "id = %s, Admin = %s zbanowal %s", nvaultKey,  admin, name);

		gNextBanId+=1;
		format(nvaultKey, 32, "%d", gNextBanId);
		nvault_set(g_vault, NEXT_BAN_ID, nvaultKey);
		
		new sParams[2];
		sParams[0] = player;
		if(showInfo)
			set_task(5.0, "DelatedKick", 0, sParams, 2);
	}	
}
public amxCban(id, level, cid){

	if(!cmd_access(id,level,cid,2))
		return PLUGIN_HANDLED;
	new argGracz[33];
	
	read_argv(1, argGracz, 32);
	
	new player = cmd_target(id, argGracz);
	
	banPlayer(id, player);
	return PLUGIN_HANDLED;
}
public client_authorized(id){
	client_banned[id] = 0;
	copy(client_ban_info[id], 255, "");
	new sid[3];
	sid[0] = id;
	client_cmd(id, "writecfg org");
	clearConsole(id);
	new i;
	new Float: opuznienie;
	opuznienie = 1.0;
	if(!is_user_connected(id))
		opuznienie = 5.0;
		
	for(i=0;i<sizeof Configi; i++){
		sid[1] = i;
		set_task(opuznienie + float(i*2), "execAndCheck", 0, sid, 3);	
	}
}

clearConsole(id){
	if(is_user_connected(id)){
		client_cmd(id, "clear");
	}
}

public taskClearConsole(params[]){
	clearConsole(params[0]);
}

/*
showCon(id, const msg[]){
	new name[64];
	get_user_name(id, name, 63);
	if(equali(name, "zabijaka"))
		client_print(id, print_console, msg);
}
*/
public execAndCheck(params[]){
	new id = params[0];
	if(is_user_connected(id)){
		client_cmd(id, "exec %s.cfg", Configi[params[1]]);
		clearConsole(id);
		set_task(1.0, "SprawdzBana", 0, params, 2);
		set_task(2.0, "taskClearConsole", 0, params, 2);
	}
}


public SprawdzBana(sid[]){
	new id = sid[0];
	
	if(is_user_connected(id) && !client_banned[id]){	
		new sBanId[33];
		new banId;
		new nvaultData[256];
		new banExists;
		new timestamp;
		
		get_user_info(id, INFO_NAME, sBanId, 32);
		if(strlen(sBanId)>0){
			banId = str_to_num(sBanId);
			if(banId>0) {
				banExists = nvault_lookup(g_vault, sBanId, nvaultData, 255, timestamp);				
				if(banExists && strfind(nvaultData, "[U]Y[/U]") >strlen(nvaultData)-10) {
					client_banned[id] = 1;
					client_cmd(id, "exec org.cfg");
					client_cmd(id, "setinfo %s ^"^"", INFO_NAME);
					clearConsole(id);
					copy(client_ban_info[id], 255, nvaultData);
					client_ban_time[id] = timestamp;
					new sParams[2];
					sParams[0] = id;
					set_task(1.0, "DelatedKick", 0, sParams, 2);
					return PLUGIN_CONTINUE;
				}
			}
		}
		client_cmd(id, "exec org.cfg");
		client_cmd(id, "setinfo %s ^"^"", INFO_NAME);
		clearConsole(id);
	}
	return PLUGIN_CONTINUE;
}

public DelatedKick(const sParams[]){
	new id = sParams[0];
	if(client_banned[id] && strlen(client_ban_info[id])>0){
		ShowInfo(id, client_ban_info[id]);
	}
}

public ShowInfo(player, const nvaultData[])
{
	new pattern[] = "\[N\](.*)\[/N\]\[A\](.*)\[/A\]";
	new num, error[128];
	new Regex:re = regex_match(nvaultData, pattern, num, error, 127);
	if (re >= REGEX_OK  && num == 3)
	{		
		new name[33];
		new admin[33];
		new czasBana[64];
		format_time ( czasBana, 63, timeFormat, client_ban_time[player]) ;

		regex_substr(re, 1, name, 32);
		regex_substr(re, 2, admin, 32);
		
		if(player && is_user_connected(player))
		{
			new strona[128];
			get_pcvar_string(gComplainUrl, strona, 127);
			client_cmd(player, "echo [ZBAN] ========================================");
			client_cmd(player, "echo [ZBAN] Masz permanentnego bana na tym serwerze!");
			client_cmd(player, "echo [ZBAN] Admin: %s", admin);
			client_cmd(player, "echo [ZBAN] Data: %s", czasBana);
			client_cmd(player, "echo [ZBAN] Bana mozesz wyjasnic na: %s", strona);
			client_cmd(player, "echo [ZBAN] ========================================");
			client_cmd(player, "disconnect");
		}

		regex_free(re)
	}
}


public ZapiszConfigi(id, banId){
	client_cmd(id, "writecfg org");
	new i;
	client_cmd(id, "setinfo %s %d", INFO_NAME, banId);
	clearConsole(id);
	for(i=0;i< sizeof Configi;i++){
		client_cmd(id, "writecfg %s", Configi[i]);		
		clearConsole(id);
	}
	client_cmd(id, "setinfo %s ^"^"", INFO_NAME);
	client_cmd(id, "exec org.cfg");
	clearConsole(id);
}

public amxCunban(id, level, cid){
	if(!cmd_access(id,level,cid,2))
		return PLUGIN_HANDLED;
	new argBanId[33];
	new banId;
	
	read_argv(1, argBanId, 32);
	banId = str_to_num(argBanId);
	if(banId>=0){
		new nvaultData[256];
		new banExists;
		new timestamp;
		new admin[64];
		get_user_name(id, admin, 63);
		
		banExists = nvault_lookup(g_vault, argBanId, nvaultData, 255, timestamp);
		if(banExists){
			copy(nvaultData, strlen(nvaultData) - 8, nvaultData);
			format(nvaultData, charsmax(nvaultData), "%s[U]N[/U]", nvaultData);
			nvault_set(g_vault, argBanId, nvaultData);
			log_to_file(CBAN_LOG_FILE, "Admin %s odbanowal banId = %s, dane = [%s]", admin, argBanId, nvaultData);
		}
	}
	return PLUGIN_HANDLED;
}


